<?php

基于 bootstrap-0-入口.php

'Illuminate\Foundation\Bootstrap\DetectEnvironment' 的功能就是加载 .env 配置文件。

对于 'Illuminate\Foundation\Bootstrap\DetectEnvironment' 来说，就是实例化这个类，并且调用 bootstrap 方法。

\vendor\laravel\framework\src\Illuminate\Foundation\Bootstrap\DetectEnvironment.php
    namespace Illuminate\Foundation\Bootstrap;

    use Dotenv\Dotenv;
    use Dotenv\Exception\InvalidPathException;
    use Symfony\Component\Console\Input\ArgvInput;
    use Illuminate\Contracts\Foundation\Application;

    class DetectEnvironment
    {
        /**
         * Bootstrap the given application.
         *
         * @param  \Illuminate\Contracts\Foundation\Application  $app
         * @return void
         */
        public function bootstrap(Application $app)
        {
            kakatest2('env', env('APP_ENV'));// 此时还没有加载 .env 文件，所以得到的是 NULL；
            kakatest2('$app->configurationIsCached()', $app->configurationIsCached());
            if (! $app->configurationIsCached()) {
                $this->checkForSpecificEnvironmentFile($app);

                try {
                    // 加载 .env 文件；
                    (new Dotenv($app->environmentPath(), $app->environmentFile()))->load();
                    kakatest2('env', env('APP_ENV'));// 此时就已经有了；
                } catch (InvalidPathException $e) {
                    //
                }
            }
        }
        ...
    }
而 Dotenv\Dotenv 在 \vendor\vlucas\phpdotenv\src\Dotenv.php
    public function __construct($path, $file = '.env')
    {
        kakatest3('\vendor\vlucas\phpdotenv\src\Dotenv.php __construct $path', $path);// 就是项目的根目录；
        kakatest3('\vendor\vlucas\phpdotenv\src\Dotenv.php __construct $file', $file);// 就是 ".env"；
        $this->filePath = $this->getFilePath($path, $file);
        $this->loader = new Loader($this->filePath, true);
    }

省去中间的步骤，找到最关键的：
\vendor\vlucas\phpdotenv\src\Loader.php
    public function setEnvironmentVariable($name, $value = null)
    {
        list($name, $value) = $this->normaliseEnvironmentVariable($name, $value);

        $this->variableNames[] = $name;

        // Don't overwrite existing environment variables if we're immutable
        // Ruby's dotenv does this with `ENV[key] ||= value`.
        if ($this->immutable && $this->getEnvironmentVariable($name) !== null) {
            return;
        }

        // If PHP is running as an Apache module and an existing
        // Apache environment variable exists, overwrite it
        if (function_exists('apache_getenv') && function_exists('apache_setenv') && apache_getenv($name)) {
            apache_setenv($name, $value);
        }
        // PHPstudy 的 apache + php5.6.31，并没有这两个函数。

        // putenv 是内置的，并不是把键值对加入到 $_ENV 内，但可以使用 getenv(key) 来获取指定的值。
        if (function_exists('putenv')) {
            putenv("$name=$value");
        }

        $_ENV[$name] = $value;
        $_SERVER[$name] = $value;
    }



额外说明一下 APP_ENV 的事情，参考 加载配置文件 的文档。